//多线程买票
#include<iostream>
#include<pthread.h>
#include<thread>
#include<string>
#include <cerrno>
#include<unistd.h>
#include<cstdlib>
#include<sys/types.h>
#include<sys/syscall.h>
#include <cerrno>
#include <cstring>
#include <cstdio>


using namespace std;
//如果多线程访问同一个全局变量，并对它进行数据计算，多线程会互相影响

//int g_val=100;//全局变量
// __thread int g_val=10; //线程的局部存储！
// __thread pid_t lwp = 0;

// __thread std::string threadname;

// pid_t gettid()
// {
//     return syscall(SYS_gettid);  //获取线程的tID
// }

// void * threadRoutine(void * args)
// {
//     string name=static_cast<const char*>(args);
//     lwp=gettid();
//     while(g_val)
//     {
//         sleep(1);
//         cout<<"main thread,g_val:"<<g_val<<",&g_val"<<&g_val<<"\n"<<endl;
//         cout<<"我是新线程："<<lwp<<endl;
//         g_val--;
//     }
//     return nullptr;
// }



// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,threadRoutine,(void*)"thread1");
//     lwp=gettid();
//     cout<<"我是主线程："<<lwp<<endl;
//     while(g_val)
//     {
//         sleep(1);
//         cout<<"main thread,g_val:"<<g_val<<",&g_val"<<&g_val<<"\n"<<endl;
//         g_val--;
//     }
//     pthread_join(tid,nullptr);
//     return 0;
// }

//////////////////////////////////////////////////////////////////////////////////
//这种就是线程不安全现象，当一个线程还在执行时（还未来得及对票数--），另一个线程就进来执行（判断票数大于零），就会出现票数为负
// int tickets=100;

// void*getTickets(void * args)
// {
//     (void)args;
//     while(true)
//     {
//         if(tickets>0)
//         {
//             sleep(1);
//             printf("%p:%d\n",pthread_self(),tickets);
//             tickets--;
//         }
//         else
//         {
//             break;
//         }
//     }
//     return nullptr;
// }



// int main()
// {
    
//     pthread_t t1,t2,t3;
//     pthread_create(&t1,nullptr,getTickets,nullptr);
//     pthread_create(&t2,nullptr,getTickets,nullptr);
//     pthread_create(&t3,nullptr,getTickets,nullptr);


//     pthread_join(t1,nullptr);  //第二个参数是返回值，这是相当于是进程中的pitwait,等待进程（回收线程）
//     pthread_join(t2,nullptr);
//     pthread_join(t3,nullptr);
//     return 0;

// }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

//线程任务
// void fun()
// {
//     while(1)
//     {
//         cout<<"hello 我是新线程"<<endl;
//         usleep(1000);
//     }
// }

// int main()
// {
//     thread  t1(fun);   //C++封装的线程
//     thread  t2(fun);
//     thread  t3(fun);
//     thread  t4(fun);

//     while(1)
//     {
//         cout<<"hello 我是主线程"<<endl;
//         sleep(1); 
//     }
//     t1.join();
//     t2.join();
//     t3.join();
//     t4.join();
// }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// __thread:修饰全局变量，带来的结果就是让每一个线程各自拥有一个全局变量---现成的局部存储

__thread int g_val=0;
// 1. 线程谁先运行与调度器相关
// 2. 线程一旦异常，都可能导致整个进程整体退出
// 3. 线程的输入和返回值问题
// 4. 线程异常退出的理解

void*threadRoutine(void*args)
{
    pthread_detach(pthread_self());   //将线程设置为可分离状态，不需要在pthread_join(),共享资源会被回收

    sleep(5);
    execl("bin/ls","ls",nullptr);       //进程程序替换
    while(1)
    {
        cout<<(char*)args<<":"<<g_val<<"&:"<<&g_val<<endl;
        g_val++;
        sleep(1);
        int a=10;
        //a/=0;
        break;
    }

    pthread_exit((void*)11);  //推荐（显示退出）
    pthread_cancel(pthread_self());  //不推推荐
    int i=0;
    int *data=new int[10];
    while(1)
    {
        cout<<"新线程："<<(char*)args<<"running..."<<pthread_self()<<endl;
        sleep(1);
        data[i]=i;
        if(i++==3) break;
        int a=100;
        //a/=0;
    }
    pthread_exit((void*)13);
    exit(10);   //不调用exit，exit是终止进程的
    cout<<"new thread quit..."<<endl;
    //return (void*)data;
    return (void*)10;// 是返回给谁呢？一般是给main thread, main如何获取到呢？pthread_join
}

int main()
{
    pthread_t tid;     //本质就是一个地址
    pthread_create(&tid,nullptr,threadRoutine,(void*)"thread 1");

    // while(1)
    // {
    //     cout<<"main thread"<<":"<<g_val<<"&:"<<&g_val<<endl;
    //     sleep(100);
    //     break;
    // }
    // int n=pthread_join(tid,nullptr);
    // cout<<"n:"<<n<<"errstring:"<<strerror(n)<<endl;
    // return 0;

    printf("%lu,%p\n",tid,tid);
    int count=0;
    while(1)
    {
      
        cout<<"main主线程："<<"running...main tid:"<<pthread_self()<<endl;
        sleep(1);
        count++;
        if(count>=5) break;
    }

    pthread_cancel(tid);
    cout<<"pthread cancel:"<<tid<<endl;

    int *ret=nullptr;
    pthread_join(tid,(void**)&ret);//默认会阻塞新线程退出

    //1、线程被取消时，join的时候，退出码是-1  #define PTHREAD_CANCELED ((void *) -1)
    PTHREAD_CANCELED;
    cout << "main thread wait done ... main quit ...: new thead quit : " << (long long)ret << "\n";
    sleep(5);

    //3、线程在创建的时候，线程也是需要进行等待的，如果主线程不等待，及会引起类似于进程僵尸问题，导致内存泄漏

    for(int i=0;i<10;i++)
    {
        cout<<ret[i]<<endl;
    }


    while(1)
    {
        cout<<"main线程："<<"running..."<<endl;
        sleep(1);
    }

    return 0;
}


